﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;

namespace VRacer.Connection
{
    /// <summary>
    /// Nasluchuje przychadzacych polaczen na serwerze i automatycznie akceptuje wszystkie nadchodzące polaczenia po czym wywoluje odpowiedni event (ConnectionAccepted).
    /// </summary>
    public class ServerConnection : ConnectionBase, IDisposable
    {
        protected const int SLEEPTIME = 250;

        private TcpListener _listener;
        private bool _isActive = false;

        private Thread _thread;

        /// <summary>
        /// Wystepuje gdy zaakceptowana nowe polaczenie od zawodnika
        /// </summary>
        public event EventHandler<ConnectionAcceptedEventArgs> ConnectionAccepted;

        public ServerConnection()
        {
            _listener = new TcpListener(IPAddress.Any, 666);
            _listener.Server.ReceiveBufferSize = 2048000;
            _listener.Server.LingerState = new LingerOption(true, 10);

            _thread = new Thread(new ThreadStart(listenForConnections));   // towrzymy nowy watek
            _thread.IsBackground = true;
        }

        /// <summary>
        /// Nasluchuje przychodzacych polaczen
        /// </summary>
        private void listenForConnections()
        {
            try
            {
                while (true)
                {
                    if (!IsActive || !_listener.Pending())
                    {
                        Thread.Sleep(SLEEPTIME);
                        continue;
                    }

                    OnConnectionAccepted(_listener.AcceptTcpClient());
                }
            }
            catch (ThreadAbortException) { }
            catch (Exception e)
            {
                Disconnect();
                throw e;
            }
        }

        protected virtual void OnConnectionAccepted(TcpClient client)
        {
            if (ConnectionAccepted != null)
                ConnectionAccepted(this, new ConnectionAcceptedEventArgs(client));
        }

        /// <summary>
        /// Zaczyna nasluchiwac przychodzacych polaczen
        /// </summary>
        public override void Connect()
        {
            _listener.Start();
            _thread.Start();
            IsActive = true;
        }

        /// <summary>
        /// Konczy zabawe - przestaje sluchac nowych polaczen
        /// </summary>
        public override void Disconnect()
        {
            IsActive = false;
            _thread.Abort();
            _listener.Stop();
        }

        /// <summary>
        /// Zwraca wartosc mowiaca czy nasluchuje nowych polaczen
        /// </summary>
        /// <value><c>true</c> jesli nasluchuje; jesli nie to, <c>false</c>.</value>
        public override bool IsActive
        {
            get { return _isActive; }
            set { _isActive = value; }
        }

        #region IDisposable Members

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
